En este apartado, se analiza la obra “La Regenta” de Leopoldo Alas Clarín a partir de diferentes técnicas de análisis de contenido. Se tratan, en su mayor parte, de acercamientos estadísticos o cuantitativos a los textos literarios. Por lo tanto, representan una visión limitada de la obra y solo complementaria a la lectura y el análisis cualitativo detenido de la misma.
Nos acercaremos al texto, primero, intentando descubrir cuáles palabras se destacan, sus frecuencias y distribuciones. Luego, analizaremos la obra desde la perspectiva de los personajes, sus relaciones y sus apariciones en la obra.
Las palabras que cuentan
El primer paso del análisis consiste en cargar los datos que hemos preparado en la sección de preparación de los datos y convertirlo en un objeto de tipo corpus. Para ello, emplearemos el paquete de R llamado quanteda, que resulta bastante completo para el análisis de contenido.
El código abajo carga los datos en la memoria, los convierte en un corpus y muestra algunas estadísticas básicas de los capítulos de la obra, como el número de palabras (tokens), el número de palabras únicas (types) y la cantidad de frases.
Code
# carga los datos de "La Regenta"load("../textos/Regenta.RData")# carga el paquete quanteda para # algunos análisislibrary(quanteda)# Elimina el título y el prólogoregc <- regc[3:nrow(regc),]# convierte en un documento corpuscp <-corpus(regc, text_field ="texto")# define los capítulos como nombre# de los documentosdocnames(cp) <- regc$capitulo# muestra estadísticas básicas de# cada capítuloreactable::reactable(summary(cp))
Vemos que los treinta capítulos de la obra tienen una extensión que va de poco más de ocho mil hasta aproximadamente veintiún mil palabras. No resulta nada sorprendente que las palabras únicas y el número de frases varían de forma proporcional.
Más interesante resulta explorar cuáles palabras se destacan en la obra. Para ello, emplearemos una técnica llamada análisis de frecuencia de palabras. En este caso, emplearemos una matriz de términos de documentos (document-feature matrix), que es una representación matricial de los textos en la que las filas representan los documentos y las columnas las palabras. Cada celda de la matriz contiene el número de veces que una palabra aparece en un documento.
Code
# convierte en una matriz de términosdtm <-dfm( tokens(cp, remove_punct =TRUE, remove_numbers =TRUE, remove_symbols =TRUE), tolower =TRUE)dtm <-dfm_remove(dtm, c(stopwords("es"),"si"))# muestra las 50 palabras más frecuentestopfeatures(dtm, 50)
don ana usted magistral aquella aquel álvaro víctor
1789 894 822 767 758 731 488 487
casa regenta señor vetusta allí ser después decía
477 467 458 455 446 430 415 414
doña vez mesía podía ahora bien ojos fermín
411 390 372 368 361 349 346 345
así iba dos quería dijo siempre menos mismo
344 333 330 328 325 325 322 318
hombre tan vida dios veces quintanar mundo mujer
314 312 311 309 305 303 285 284
todas sabía ver tiempo alma día parecía amor
279 279 279 278 275 271 267 267
aquello decir
265 257
En este caso, hemos considerado palabras aisladas, pero podemos repetir el análisis con bigramas o trigramas, que son secuencias de dos o tres palabras consecutivas. Estas combinaciones permiten encontrar secuencias de ideas que pueden revelar ciertos contenidos o patrones en el texto.
Code
tk <-tokens(cp, remove_punct =TRUE, remove_numbers =TRUE, remove_symbols =TRUE)tk <-tokens_remove(tk, stopwords("es"))bi <-tokens_ngrams(tk, n =2)# convierte en una matriz de términosdtm <-dfm(bi)# muestra los 50 bigramas más frecuentestopfeatures(dtm, 50)
¿Qué vemos en los resultados de los bigramas y trigramas? El primer patrón que emerge es la presencia de nombres de personajes, como “don Víctor Quintanar”, “don Álvaro” o “do Fermín”. También aparecen nombres de lugares, como “Vetusta” o “Santa Cruz”. Por último, encontramos algunas secuencias que parecen describir acciones o situaciones, como “señor marqués” o “señor don Fermín”.
dicf <-dictionary(list(familia=c("padre", "madre", "hijo", "hija", "hermano", "hermana"),sociedad=c("vetustense","puebl","ciudad","conversa","amig","noble","arist")))plotLexDiv(cp, dicf, title ="La Regenta", subtitle ="Familia y sociedad en la novela", palette = pal$cat.awtools.spalette.6[1:2])
Repetimos el mismo gráfico, ahora con las categorías de tiempo y espacio:
Code
dicf <-dictionary(list(espacio=c("casino","catedral","vivero","casa","espolón","teatro"),tiempo=c("otoño","verano","invierno","primavera","semana santa","navidad")))plotLexDiv(cp, dicf, title ='La Regenta', subtitle ="Espacio y tiempo en la novela", palette = pal$cat.brewer.Dark2.8[c(1:4)])
Code
dicf <-dictionary(list(social=c("casino","teatro","espolón","Paseo de Verano","Paseo de los curas","calle","plaza"),religioso=c("catedral","capilla","sacristía","claustro","seminario"), doméstico=c("vivero","\\bcasa\\b","hogar","alcoba","habitación","cama")))ft <-filterWords(cp, dicf)ft$name[ft$name!="002 - Prólogo"] <-paste0("Capítulo ",ft$name[ft$name!="002 - Prólogo"])plotSpike(ft, title ='Los espacios de "La Regenta"', subtitle ="Gráfico de dispersión léxica para distintos tipos de espacio.", palette = pal$cat.brewer.Dark2.8[c(1:4)],label.size =3, line.width =0.3, ring.col="black")
dich <-dictionary(list(hombres=list(Alvaro=c("Álvaro Mesía","Álvaro","Mesía","presidente del casino"),Saturnino=c("Saturnino Bermúdez","Saturnino","Bermúdez","Saturno","Saturnillo"),Fermin=c("Magistral","Provisor","Fermín","De Pas","Fermín de Pas","Magistral"),Victor=c("Víctor","Víctor Quintanar","Quintanar"),Otros=c("Agustinito","Amadeo","Anacleto","Anselmo","Antero","Antón Raíces","Antonio","Barcaza","Basilio","Bautista","Bedoya","Belisario","Benítez","Bismark","Campillo","\\b[C]hato\\b","don Carlos","Peláez","Cayetano","Cayetano Ripamilán","Ripamilán","Celedonio","Colás","marqués de Corujedo","Frígilis","Crespo","Custodio","Olías de Cuervo","señor Cuervo","Diego","Escosura","\\b[E]studiante\\b","Pepe","Trabuco","Foja","Fortunato","Francisco de Asís","Francisco de Pas","Francisco de Osuna","Francisco Páez", "señor Páez", "señor de Páez","Francisco Carraspique","Froilán","don Frutos","Frutos Redondo","Fulgosio","Germán","Glocester","Restituto","señor Infanzón", "el Infanzón","Iriarte","Joaquinito","Juanito","Leando","Maroto","marqués de Vegallana","\\s{1}[M]arqués\\b","Martínez","Matías","Matiella","monaguillo","señor Orgaz","\\b[P]alma\\b","Paco","Paquito","Palomo","Rodríguez","Parcerisa","Pedro","\\b[P]erales\\b","Pinón","Pompeyo","Pompeyo Guimarán","Guimarán","Robustiano","señor Roque","Rosendo","don Santos","Sousa","Trifón","\\b[V]inagre\\b","Vinculete") ),mujeres=list(Ana=c("Ana","Anita","Regenta"),Obdulia=c("Obdulia","Obdulia Fandiño","Fandiño","Obdulita"),Otras=c("Agapita","Águeda","Angelina","Anuncita","doña Anuncia","Camila","Carolina","Señora de Infanzón", "la Infanzón","Celestina","Edelmira","Emma","Fabiolita","Fulgencia","Gertrudis","la González","Juana","Lola","doña Lucía","marquesa","Rufina","Olvido","doña Paula","Pepa","Guimarán, Perpétua","\\b[P]ilar\\b","Petra","doña Petronila","Ramona","\\bRita\\b","\\bRosa\\b","Rosita","Rudesinda","Servanda","Társila","\\b[T]eresa\\b","Teresina","Úrsula","Visitación","\\b[V]isita\\b","viuda del marqués de Corujedo") ) ))xp <-countKeywords(cp, dich, rel.freq = F, group.var ="capitulo",quietly =TRUE)# Agrega los resultados por los dos niveles# de código del diccionarioxx <-aggregate(list(frequency=xp$frequency), by=list(groups=xp$groups, level1=xp$level2), sum, na.rm=T)# Elimina los términos no encontrados# en el corpusxx <- xx[xx$frequency>0,]# Ordena por capítuloxx <- xx[order(xx$groups),]plotSankey(xx, from ="level1", to="groups", value ="frequency", opacity =0.05)
# Reorganiza el corpus según# sentencias o frasescs <-corpus_reshape(cp, "sentences")# Calcula la frecuencia en la# que dos codigos del mismo # diccionario aparecen juntos# en cada frased1 <-matchCodes(cs, dic, level =1, quietly=TRUE)# Ordena los resultados de mayor a menord1 <- d1[order(d1$value, decreasing = T),]plotChord(d1, from ="term1", to ="term2", value="value")
Ahora con los personajes
Code
# Reorganiza el corpus según# sentencias o frasescs <-corpus_reshape(cp, "sentences")# Calcula la frecuencia en la# que dos codigos del mismo # diccionario aparecen juntos# en cada frased1 <-matchCodes(cs, dich, level =2, quietly=TRUE)# Ordena los resultados de mayor a menord1 <- d1[order(d1$value, decreasing = T),]plotChord(d1, from ="term1", to ="term2", value="value", elementId ="chord2")